package fnic.prehand.esagent.activity_measure;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.common.xcontent.json.JsonXContentParser;

import fnic.jsontrans.DeviceId;
import fnic.jsontrans.ErrorCode;
import fnic.jsontrans.PCJsonToCtrl;
import fnic.jsontrans.ProbeAddress;
import fnic.prehand.common.PbAddrMapService;
 
public class ProbeAgent extends CommonAgent{
	private static final Logger logger = Logger.getLogger(ProbeAgent.class);
	
	private final PbAddrMapService pbAddrInstance;
//	String probeAddrUrl; 
	private PCJsonToCtrl oneCtrl;
	private ArrayList<PCJsonToCtrl> pcCtrlList;

	public ProbeAgent(String idx, String type, String ctrlUrl, String skUrl, String pbAddrUrl) {
		super(idx, type, ctrlUrl, skUrl);
//		probeAddrUrl = pbAddrUrl;
		pbAddrInstance  = new PbAddrMapService(pbAddrUrl);
		pcCtrlList = new ArrayList<PCJsonToCtrl>();
	}

	@Override
	protected boolean parseHead(String head, Jsonmaps maps) {
		JsonXContentParser headparser=null;
		Map<String, Object> headmap=null;
		boolean parseflg = true;
		
		try {
			headparser = (JsonXContentParser) jsoncontent.createParser(head);
			headmap = headparser.map();
		} catch (IOException e) {
			logger.error("parse head fail, reason:"+e.getMessage());
			parseflg = false;
		}finally{
			if(headparser!=null){
				headparser.close();
			}
			if(!parseflg || headmap==null){
				return false;
			}
		}
		
		if(headmap.containsKey(DeviceId.COND_PROBE_TYPE)){
			probeType = (Integer)headmap.get(DeviceId.COND_PROBE_TYPE);
		}else{
			probeType = 1;
		}
		probeId = (Integer)headmap.get(DeviceId.COND_PROBE_ID);
		
		long time = System.currentTimeMillis();
		Date date = new Date(time);
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String probeTime = dateFormat.format(date);
		
		int taskId = (Integer) headmap.get(DeviceId.COND_TASK_ID);
		int execNum = (Integer) headmap.get(DeviceId.COND_EXEC_NUM);
		String sessionKey = (String) headmap.get(DeviceId.COND_PROBE_SESSION);
		oneCtrl = new PCJsonToCtrl(probeType, probeId, taskId, execNum, probeTime);
		headmap.put("probetime", probeTime);
		
		if(headmap.containsKey(DeviceId.COND_PROBE_SESSION)){
			if(!validSK(sessionKey)){
				oneCtrl.setindexid("-2"); // sessionKey校验失败
				oneCtrl.setStatus(ErrorCode.index_failed);
				oneCtrl.setErrorno(ErrorCode.sessionKeyErrCode);
				setFailmsg(jsonInstance.Obj2String(oneCtrl));
				return false;
			}
		}
		headmap.remove(DeviceId.COND_PROBE_SESSION);

		//probetype,probetype冗余，兼容之前的手机发布版本
		headmap.put("probeType", probeType);
		headmap.put("probetype", probeType);
		headmap.put("probeid", probeId);
		maps.setHeadmap(headmap);
		return true;
	}

	@Override
	protected boolean parseBody(String body, Jsonmaps maps) {
		JsonXContentParser bodyparser=null;
		Map<String, Object> bodymap=null;
		boolean parseflg = true;
		
		try {
			bodyparser = (JsonXContentParser) jsoncontent.createParser(body);
			bodymap = bodyparser.map();
		} catch (IOException e) {
			logger.error("parse body fail, reason:"+e.getMessage());
			parseflg = false;
		}finally{
			if(bodyparser!=null){
				bodyparser.close();
			}
			if(!parseflg || bodymap == null){
				oneCtrl.setindexid("-1"); // 测试结果json解析失败
				oneCtrl.setStatus(ErrorCode.index_failed);
				oneCtrl.setErrorno(ErrorCode.jsonErrCode);
				setFailmsg(jsonInstance.Obj2String(oneCtrl));
				return false;
			}
		}
		
		dealProbeReq(bodymap);
		pcCtrlList.add(oneCtrl);

		maps.setBodymap(bodymap);
		return true;
	}
	
	@Override
	protected void dealBulkIndexRsp(BulkResponse response) {
		if(response == null){
			return;
		}
		if(response.hasFailures()){
			logger.error("failed to execute" + response.buildFailureMessage());
		}

		
		Iterator<BulkItemResponse> rspitor = response.iterator();
		int pos = 0;
		while (rspitor.hasNext()) {

			if (pcCtrlList.get(pos).getStatus() == ErrorCode.index_failed) {
				pos++;
				continue;
			}
			BulkItemResponse rsp = rspitor.next();
			if (!rsp.isFailed()) {
				pcCtrlList.get(pos).setindexid(rsp.getId());
				pcCtrlList.get(pos).setStatus(ErrorCode.index_success);
				pcCtrlList.get(pos).setErrorno(0);
			} else {
				logger.error("bulk error details: position:" + pos + ", failmsg:" + rsp.getFailureMessage());
				pcCtrlList.get(pos).setindexid("-2"); // 批量索引失败
				pcCtrlList.get(pos).setStatus(ErrorCode.index_failed);
				pcCtrlList.get(pos).setErrorno(ErrorCode.indexErrCode);
			}
			pos++;
		}
		
		sendIdxResult(jsonInstance.Obj2String(pcCtrlList), false);
		pcCtrlList = new ArrayList<PCJsonToCtrl>();
	}

	private void dealProbeReq(Map<String, Object> maps) {
		// 获取地区信息，本地获取不成功到管理节点获取
		ProbeAddress pbaddr = pbAddrInstance.getProbeAddr(probeId);
		if (pbaddr != null) {
			maps.put("countryid", pbaddr.getCountry());
			maps.put("provinceid", pbaddr.getProvinceId());
			maps.put("cityid", pbaddr.getCityId());
			maps.put("areaid", pbaddr.getAreaId());
			maps.put("address", pbaddr.getAddress());
		}
	}

	@Override
	protected void dealSingleIndexRsp(IndexResponse response) {
		// TODO Auto-generated method stub
		if(response != null){
			oneCtrl.setindexid(response.getId());
			oneCtrl.setStatus(ErrorCode.index_success);
			oneCtrl.setErrorno(0);
		}else{
			oneCtrl.setindexid("-2"); // 批量索引失败
			oneCtrl.setStatus(ErrorCode.index_failed);
			oneCtrl.setErrorno(ErrorCode.indexErrCode);
		}
		sendIdxResult(jsonInstance.Obj2String(pcCtrlList), false);
	}
	
	

}
